home *** CD-ROM | disk | FTP | other *** search
- #include <windows.h>
- #include <math.h>
- #include "windxf.h"
- #include <stdlib.h>
- #include <stdio.h>
-
- extern HWND GBL_hwnd;
- extern HDC mfhdc;
- extern HDC GBL_hdc;
-
- typedef struct {
- int number;
- char marker[80];
- } DXF_STATE;
-
- #define NUM_STATES 30
-
- DXF_STATE statetab[] = { 0,"SECTION", /* Section Begin 1 */
- 2,"HEADER", /* Header 2 */
- 0,"ENDSEC", /* End Section 3 */
- 2,"TABLES", /* Tables section 4 */
- 0,"TABLE", /* Table Begin 5 */
- 2,"VPORT", /* Viewport 6 */
- 70,"#", /* 70 with a count 7 */
- 0,"ENDTAB", /* End of table 8 */
- 9,"$EXTMIN", /* Min Extents 9 */
- 9,"$EXTMAX", /* Max Extents 10 */
- 10,"#", /* X coord 11 */
- 20,"#", /* Y coord 12 */
- 2,"ENTITIES", /* Entities 13 */
- 11,"#", /* X2 coord 14 */
- 21,"#", /* Y2 coord 15 */
- 0,"LINE", /* Line Entity 16 */
- 0,"ATTDEF", /* Attribute Def 17 */
- 8, "#", /* Layer Name 18 */
- 40,"#", /* Height 19 */
- 1, "#", /* Primary Text 20 */
- 2, "#", /* Name 21 */
- 3, "#", /* Other Text 22 */
- 50,"#", /* Angle 23 */
- 51,"#", /* Angle 24 */
- 0, "ARC", /* Arc 25 */
- 0, "POLYLINE",/* Polyline 26 */
- 0, "VERTEX", /* Vertex 27 */
- 0, "SEQEND", /* End Sequence 28 */
- 66, "#", /* Entities Follow 29 */
- 41, "#", /* End Width 30 */
- };
-
- typedef enum {
- NUMBER,
- MARKER,
- } READ_STATE;
-
- READ_STATE curstate = NUMBER;
-
-
- char layer[256], heightstr[256], textstr[256];
- double wx1, wy1, wx2, wy2;
- int logextx, logexty;
-
- int
- ReadDXF(dxfname)
- char * dxfname;
- {
- int fd;
- char line1[256], line2[256];
- int st;
- double x, y;
- int color;
- char msg[256];
- int xi,yi;
- int lx, ly;
-
- int section_active = 0;
- int header_active = 0;
- int entities_active = 0;
- int tables_active = 0;
- int table_start = 0;
- int polyline_count = 0;
-
- double height, radius, st_ang, end_ang;
-
- MSG msg1;
-
- fd = _lopen(dxfname, OF_READ);
-
-
- while (1)
- {
- PeekMessage(&msg1, GBL_hwnd,(WORD)0,(WORD)0,PM_NOREMOVE);
-
- if (getline(line1, 256, fd) == NULL)
- break;
-
- if (getline(line2, 256, fd) == NULL)
- break;
-
- st = dxfstate(line1, line2);
- switch(st)
- {
- case 1: /* Section */
- section_active = 1;
- break;
- case 2: /* Header */
- header_active = 1;
- break;
- case 3: /* End Section */
- section_active = 0;
- /* Whatever section was active, shut it down */
- if (header_active)
- header_active = 0;
- else
- if (entities_active)
- entities_active = 0;
- else
- if (tables_active)
- tables_active = 0;
- break;
-
- case 4: /* Tables Active */
- tables_active = 1;
- break;
- case 5: /* Table */
- table_start = 1;
- break;
- case 8: /* End table */
- table_start = 0;
- break;
- case 9: /* Min Extents */
- get_followxyfloat(fd, &wx1, &wy1);
- break;
- case 10: /* Max Extents */
- get_followxyfloat(fd, &wx2, &wy2);
- color = 7;
-
- /* Now we're ready to set our world coords.
- Adjust the smaller of the axis to form
- a square world coordinate system */
-
- if ( (wy2 - wy1) > (wx2 - wx1) )
- {
- wx2 += (((wy2-wy1)/(wx2-wx1))*(wx2-wx1))/2.0;
- wx1 -= (((wy2-wy1)/(wx2-wx1))*(wx2-wx1))/2.0;
- }
- else
- {
- wy2 += (((wx2-wx1)/(wy2-wy1))*(wy2-wy1))/2.0;
- wy1 -= (((wx2-wx1)/(wy2-wy1))*(wy2-wy1))/2.0;
- }
- break;
-
- case 13: /* Entities */
- entities_active = 1;
- break;
-
- case 16: /* Line Entities */
- if (entities_active)
- {
- get_followxyfloat(fd, &x, &y);
- MapUsertoLog(x,y,&lx,&ly);
- MoveTo(GBL_hdc, lx, ly);
- MoveTo(mfhdc, lx, ly);
- get_followxyfloat(fd, &x, &y);
- MapUsertoLog(x,y,&lx,&ly);
- LineTo(GBL_hdc, lx, ly);
- LineTo(mfhdc, lx, ly);
- }
- break;
-
- case 17: /* Attribute Def */
- get_followline(fd, 18, layer);
- get_followxyfloat(fd, &x, &y);
- get_followline(fd, 19, heightstr);
- height = atof(heightstr);
- get_followline(fd, 20, textstr);
- break;
-
- case 25: /* Arc */
- get_followarc(fd, &x,&y,&radius,&st_ang,&end_ang);
- /* MS Windows doesn't support an arc the way DXF does,
- so we'll leave this one for a future version */
- /* movabs(&x,&y);
- arc(&radius,&end_ang,&st_ang); */
- break;
-
- case 26: /* Polyline */
- if (entities_active)
- {
- get_followline(fd, 18, textstr);
- get_followline(fd, 29, textstr);
- /* Polyline is justing setting us up to read
- vertices */
- polyline_count = 0;
- }
- break;
- case 27: /* Vertex */
- if (entities_active)
- {
- get_followxyfloat(fd, &x, &y);
- MapUsertoLog(x,y,&lx,&ly);
- if (polyline_count==0)
- {
- /* If this is the first vertex, move to it */
- MoveTo(GBL_hdc, lx, ly);
- MoveTo(mfhdc, lx, ly);
- }
- else
- {
- /* Line to subsequent vertices */
- LineTo(GBL_hdc, lx, ly);
- LineTo(mfhdc, lx, ly);
- }
- polyline_count++;
- }
- break;
-
- case 28: /* Sequence end */
- if (entities_active)
- {
- if (polyline_count > 0)
- polyline_count = 0;
- }
- break;
- } /* end of switch */
- } /* end of while(1) */
- _lclose(fd);
- return 1;
- }
-
- int dxfstate(line1, line2)
- char * line1;
- char * line2;
- {
- int ctr;
- int num;
- int l;
-
- num = atoi(line1);
- l = lstrlen(line2);
-
- for (ctr=0; ctr < NUM_STATES; ctr++)
- {
- if ( (statetab[ctr].number == num) &&
- (!lstrcmp(statetab[ctr].marker,line2)))
- return ctr+1;
- if ( (statetab[ctr].number == num) &&
- (!lstrcmp(statetab[ctr].marker,"#")))
- return ctr+1;
- }
-
- return -1;
- }
-
- int
- get_followxyfloat(fd, x, y)
- int fd;
- double * x;
- double * y;
- {
- long pos;
- int ctr, st2;
- char line1[256], line2[256];
- double p1, p2;
-
- char msg[256];
-
-
- pos = _llseek(fd,0L,1);
- ctr = 0;
- while (ctr < 2)
- {
- getline(line1, 256, fd);
- getline(line2, 256, fd);
- st2 = dxfstate(line1, line2);
- if ( (st2 == -1) || (st2 == 18) )
- continue;
- if ( (st2 == 11) || (st2 == 14) )
- {
- p1 = atof(line2);
- *x = p1;
- ctr++;
- continue;
- }
- if ( (st2 == 12) || (st2 == 15) )
- {
- p2 = atof(line2);
- *y = p2;
- ctr++;
- continue;
- }
- _llseek(fd, pos, 0);
- }
-
- return 1;
- }
-
- int
- get_followline(fd, st, line)
- int fd;
- int st;
- char * line;
- {
- long pos;
- int st2;
- char line1[256], line2[256];
-
- pos = _llseek(fd,0L,1);
- while (1)
- {
- getline(line1, 256, fd);
- getline(line2, 256, fd);
- st2 = dxfstate(line1, line2);
- if (st2 == -1)
- continue;
- if (st2 == st)
- {
- lstrcpy(line, line2);
- break;
- }
- _llseek(fd, pos, 0);
- }
- return 1;
- }
-
- int
- get_followarc(fd, x, y, radius, st_ang, end_ang)
- int fd;
- double * x;
- double * y;
- double * radius;
- double * st_ang;
- double * end_ang;
- {
- long pos;
- int ctr, st2;
- char line1[256], line2[256];
-
- pos = _llseek(fd,0L,1);
- ctr = 0;
- while (ctr < 5)
- {
- getline(line1, 256, fd);
- getline(line2, 256, fd);
- st2 = dxfstate(line1, line2);
- if ( (st2 == -1) || (st2 == 18) )
- continue;
- if ( (st2 == 11) || (st2 == 14) )
- {
- *x = atof(line2);
- ctr++;
- continue;
- }
- if ( (st2 == 12) || (st2 == 15) )
- {
- *y = atof(line2);
- ctr++;
- continue;
- }
- if ( st2 == 19 )
- {
- *radius = atof(line2);
- ctr++;
- continue;
- }
- if ( st2 == 23 )
- {
- *st_ang = atof(line2);
- ctr++;
- continue;
- }
- if ( st2 == 24 )
- {
- *end_ang = atof(line2);
- ctr++;
- continue;
- }
- _llseek(fd, pos, 0);
- }
- return 1;
- }
-
- /* Windows doesn't support fgets, so we have to write
- our own binary, unbuffered version. This program could
- be greatly enhanced by implementing a look ahead buffer
- here */
-
- int getline(line, lim, fd)
- char * line;
- int lim;
- int fd;
- {
- int ctr;
- int nread;
- long backup;
- long newpos;
-
- nread = _lread(fd, line, lim-1);
-
- if (nread < lim-1)
- {
- return 0;
- }
-
- for (ctr=0; ctr < lim-1; ctr++)
- if ( (line[ctr] == (char)13) &&
- (line[ctr+1] == (char)10) )
- {
- line[ctr] = (char)NULL;
- backup = ctr - lim + 3;
- newpos = _llseek(fd, (long)backup, 1);
- return 1;
- }
- line[lim-1] = '\0';
-
- /* Should never get here... */
- MessageBox(GBL_hwnd, "Didn't hit loop", (LPSTR) NULL, MB_OK);
- }
-
- /* maps user coordinates to logical device coordinates */
- int
- MapUsertoLog(x,y,lx,ly)
- double x;
- double y;
- int * lx;
- int * ly;
- {
- *lx = (int) (((x-wx1)/(wx2-wx1)) * (double)1000);
- *ly = (int) (((y-wy1)/(wy2-wy1)) * (double)1000);
- *ly = 1000 - *ly;
- }